package mx.com.crowdgine.entity.geometry;

import java.nio.FloatBuffer;

import com.jogamp.common.nio.Buffers;
import javax.media.opengl.GL4bc;
import javax.media.opengl.glu.GLU;

import mx.com.crowdgine.assetloader.Texture;
import mx.com.crowdgine.assetloader.RawTexture;
import mx.com.crowdgine.entity.Entity;
import mx.com.crowdgine.util.math.Vector3f;

public class Plane implements Entity{
	
	private float size;
	private Vector3f position;
	private int vertexCount;
	
	private float vertices[];
	private Vector3f color;
	
	Texture texture = null;
	private boolean hasTexture = false;
	
	private FloatBuffer vertexBuffer;
	private FloatBuffer colorBuffer;
	
	public Plane(float size) {
		this.size = size;
		this.position = new Vector3f(0,0,0);
		this.initVertices();
		this.hasTexture = false;
		this.color = new Vector3f(1.0f, 0.0f, 0.0f);
		this.createBuffers();
	}
	
	public Plane(float size, Vector3f position){
		this.position = position;
		this.size = size;
		this.initVertices();
		this.hasTexture = false;
		this.color = new Vector3f(1.0f, 0.0f, 0.0f);
		this.createBuffers();
	}
	
	public Plane(float size, String texture){
		this.size = size;
		this.initVertices();
		this.hasTexture = this.initTexture(texture);
		this.color = Vector3f.ZERO;
		this.createBuffers();
	}
	
	public Plane(float size, Vector3f position, Vector3f color){
		this.size = size;
		this.position = position;
		this.initVertices();
		this.hasTexture = false;
		this.color = color;
		this.createBuffers();
	}
	
	public Plane(Vector3f width, Vector3f height, Vector3f position){
		this.vertices = new float[3*6];
		this.position = position;
		// First triangle
		this.vertices[0] = 0;
		this.vertices[1] = 0;
		this.vertices[2] = 0;
		
		this.vertices[3] = width.getX();
		this.vertices[4] = width.getY();
		this.vertices[5] = width.getZ();
		
		this.vertices[6] = height.getX();
		this.vertices[7] = height.getY();
		this.vertices[8] = height.getZ();
		
		//Second triangle
		this.vertices[9] = width.getX();
		this.vertices[10] = width.getY();
		this.vertices[11] = width.getZ();
		
		this.vertices[12] = width.getX() + height.getX();
		this.vertices[13] = width.getY() + height.getY();
		this.vertices[14] = width.getZ() + height.getZ();
		
		this.vertices[15] = height.getX();
		this.vertices[16] = height.getY();
		this.vertices[17] = height.getZ();
		
		this.translate(position);
		this.hasTexture = false;
		this.color = new Vector3f(1.0f, 0.5f, 0.0f);
		this.createBuffers();
	}
	
	public Plane(Vector3f width, Vector3f height, Vector3f position, Vector3f color){
		this.vertices = new float[3*6];
		this.position = position;
		// First triangle
		this.vertices[0] = 0;
		this.vertices[1] = 0;
		this.vertices[2] = 0;
		
		this.vertices[3] = width.getX();
		this.vertices[4] = width.getY();
		this.vertices[5] = width.getZ();
		
		this.vertices[6] = height.getX();
		this.vertices[7] = height.getY();
		this.vertices[8] = height.getZ();
		
		//Second triangle
		this.vertices[9] = width.getX();
		this.vertices[10] = width.getY();
		this.vertices[11] = width.getZ();
		
		this.vertices[12] = width.getX() + height.getX();
		this.vertices[13] = width.getY() + height.getY();
		this.vertices[14] = width.getZ() + height.getZ();
		
		this.vertices[15] = height.getX();
		this.vertices[16] = height.getY();
		this.vertices[17] = height.getZ();
		
		this.translate(position);
		this.hasTexture = false;
		this.color = color;
		this.createBuffers();
	}
	
	private boolean initTexture(String file){
		//try {
			//Load image and create JOGL texture
			//return true;
		//} catch (MalformedURLException e) {
			//e.printStackTrace();
			//System.out.println("Plane: Bad texture URL");
			//return false;
		//} catch (IOException e) {
			//e.printStackTrace();
			//System.out.println("Plane: Texture file not found");
			//return false;
		//}
		return false;
	}

	private void initVertices() {
		this.vertices = new float[3*6];
		float offset = size/2;
		// First triangle
		this.vertices[0] = position.getX()-offset;
		this.vertices[1] = position.getY()-offset;
		this.vertices[2] = position.getZ();
		
		this.vertices[3] = position.getX()+offset;
		this.vertices[4] = position.getY()-offset;
		this.vertices[5] = position.getZ();
		
		this.vertices[6] = position.getX()+offset;
		this.vertices[7] = position.getY()+offset;
		this.vertices[8] = position.getZ();
		
		//Second triangle
		this.vertices[9] = position.getX()-offset;
		this.vertices[10] = position.getY()-offset;
		this.vertices[11] = position.getZ();
		
		this.vertices[12] = position.getX()+offset;
		this.vertices[13] = position.getY()+offset;
		this.vertices[14] = position.getZ();
		
		this.vertices[15] = position.getX()-offset;
		this.vertices[16] = position.getY()+offset;
		this.vertices[17] = position.getZ();
	}
	
	public float getSize() {
		return size;
	}

	public void setSize(float size) {
		throw new UnsupportedOperationException();
	}
	
	public boolean bindTexture(int target){
		if(this.hasTexture){
			//TODO: Binding logic to bind OGL texture
			throw new UnsupportedOperationException();
		}
		return false;
	}
	
	public boolean unbindTexture(int target){
		//TODO: Unbinding logic to unbind OGL texture
		throw new UnsupportedOperationException();
	}
	
	public void translate(Vector3f trans){
		for(int i=0; i<vertices.length; i+=3){
			this.vertices[i + 0] += trans.getX();
			this.vertices[i + 1] += trans.getY();
			this.vertices[i + 2] += trans.getZ();
		}
		position.set(position.getX()+trans.getX(), position.getY()+trans.getY(), position.getZ()+trans.getZ());
	}
	
	@Override
	public boolean hasTexture(){
		return hasTexture;
	}
	
	private void createBuffers(){
		vertexBuffer = Buffers.newDirectFloatBuffer(vertices);
		
		vertexCount = vertices.length/3;
		
		float [] vertexColors = new float[this.vertices.length];
		for(int i = 0; i <= vertexColors.length - 3; i+=3) {
			vertexColors[i + 0] = color.getX();
			vertexColors[i + 1] = color.getY();
			vertexColors[i + 2] = color.getZ();
		}
		
		colorBuffer = Buffers.newDirectFloatBuffer(vertexColors);
	}
	
	@Override
	public FloatBuffer getVertices() {
		return vertexBuffer;
	}
	
	@Override
	public FloatBuffer getVertexColors() {
		return colorBuffer;
	}

	@Override
	public Vector3f getPosition() {
		return position;
	}

	@Override
	public int getVertexCount() {
		return vertexCount;
	}
	
	public boolean initRawTexture(RawTexture texture,GL4bc gl,GLU glu){
		texture.buildTexture(gl, glu);
		gl.glEnable(GL4bc.GL_TEXTURE_2D); 
		return false;
	}

}
